package org.termine.jsf;

import java.io.Serializable;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.termine.db.RedisConnector;
import org.termine.entity.Location;
import org.termine.entity.ServiceSelectItem;
import org.termine.logic.ServiceManager;
import org.termine.util.ConfigurationBean;
import org.termine.util.GeoCoder;

@ManagedBean
@ViewScoped
public class AppointmentFirstStageJSF extends BaseJSF implements Serializable {

	private static final long serialVersionUID = -2895978536940711419L;
	private static final Logger logger = LoggerFactory.getLogger(AppointmentFirstStageJSF.class);

	@ManagedProperty(value = "#{serviceManager}")
	private ServiceManager serviceManager;
	@ManagedProperty(value = "#{loginJSF}")
	private LoginJSF loginJSF;
	@ManagedProperty(value = "#{redisConnector}")
	private RedisConnector redisConnector;
	@ManagedProperty(value="#{configurationBean}")
	private ConfigurationBean configurationBean;

	private List<ServiceSelectItem> services;
	private List<ServiceSelectItem> filteredServices;
	private ServiceSelectItem selectedService;
	private Location location;

	/*
	 * Init
	 */
	@PostConstruct
	public void init() {
		this.services = this.getServiceManager().getAllAvailableServices(
				this.getLoginJSF().getPersonalData().getProvider_id());
		this.location = this.getLoginJSF().getLocation().copy();
		this.selectedService = null;
	}

	/*
	 * Jsf Action Methods
	 */
	public String proceed() {
		if (this.selectedService == null) {
			this.setErrorMessage("A service must be selected to proceed!");
			return "ERROR";
		}
		if (!this.location.isValid()) {
			this.setErrorMessage("The location is not valid!");
			return "ERROR";
		}
		try {
			GeoCoder.setPosition(this.location);
		} catch (Exception e) {
			logger.error("ERROR: ", e);
			this.setFatalMessage("An error occurred!");
			return "ERROR";
		}
		this.setLocation(this.location);
		this.setSelectedService(this.selectedService);
		return "SUCCESS";
	}

	/*
	 * Session Variables
	 */
	public ServiceSelectItem getSelectedService() {
		if (Boolean.parseBoolean(this.configurationBean.getProperty("use_redis"))) {
			return (ServiceSelectItem) this.redisConnector.get(this.getLoginJSF().getSessionKey()
					+ "_selectedservice");
		} else {
			return this.selectedService;
		}
	}

	public void setSelectedService(ServiceSelectItem selectedService) {
		if (Boolean.parseBoolean(this.configurationBean.getProperty("use_redis"))) {
			this.redisConnector.setExp(this.getLoginJSF().getSessionKey() + "_selectedservice",
					RedisConnector.toString(selectedService));
		} else {
			this.selectedService = selectedService;
			FacesContext.getCurrentInstance().getExternalContext().getSessionMap()
			.put(this.getLoginJSF().getSessionKey() + "_selectedservice", selectedService);
		}
	}

	public Location getLocation() {
		if (Boolean.parseBoolean(this.configurationBean.getProperty("use_redis"))) {
			return (Location) this.redisConnector.get(this.getLoginJSF().getSessionKey()
					+ "_selectedlocation");
		} else {
			return this.location;
		}
	}

	public void setLocation(Location location) {
		if (Boolean.parseBoolean(this.configurationBean.getProperty("use_redis"))) {
			this.redisConnector.setExp(this.getLoginJSF().getSessionKey() + "_selectedlocation",
					RedisConnector.toString(location));
		} else {
			this.location = location;
			FacesContext.getCurrentInstance().getExternalContext().getSessionMap()
			.put(this.getLoginJSF().getSessionKey() + "_selectedlocation", location);
		}
	}

	/*
	 * Getters & Setters
	 */
	public List<ServiceSelectItem> getServices() {
		return this.services;
	}

	public void setServices(List<ServiceSelectItem> services) {
		this.services = services;
	}

	public List<ServiceSelectItem> getFilteredServices() {
		return this.filteredServices;
	}

	public void setFilteredServices(List<ServiceSelectItem> filteredServices) {
		this.filteredServices = filteredServices;
	}

	public ServiceManager getServiceManager() {
		return this.serviceManager;
	}

	public void setServiceManager(ServiceManager serviceManager) {
		this.serviceManager = serviceManager;
	}

	public LoginJSF getLoginJSF() {
		return this.loginJSF;
	}

	public void setLoginJSF(LoginJSF loginJSF) {
		this.loginJSF = loginJSF;
	}

	public RedisConnector getRedisConnector() {
		return this.redisConnector;
	}

	public void setRedisConnector(RedisConnector redisConnector) {
		this.redisConnector = redisConnector;
	}

	public ConfigurationBean getConfigurationBean() {
		return this.configurationBean;
	}

	public void setConfigurationBean(ConfigurationBean configurationBean) {
		this.configurationBean = configurationBean;
	}

}